include('shared.lua')

ENT.Materials = {}
ENT.Materials ["Black"] = Material("sprites/MMBlack")
ENT.Materials ["CameraTan"] = Material("sprites/MMCamTan")
ENT.Materials ["CameraDir"] = Material("sprites/MMCamDir")
ENT.Materials ["CameraPos"] = Material("sprites/MMCamPos")
ENT.Materials ["RoleplayPos"] = Material("sprites/MMRoleplayPos")
ENT.Materials ["RoleplayNode"] = Material("sprites/MMRoleplayNode")
ENT.Materials ["Highlight"] = Material("sprites/MMHighlight")
ENT.Materials ["Grip"] = Material("sprites/MMGrip")
ENT.HighlightAngle = 0.0

//****************************************************
//* Renders a curve segment wrt the parameters
function ENT:DrawHighlighted()
	if gDisplayJunk == true  then
		render.SetMaterial(self.BaseClass.Materials["Highlight"])
		self.HighlightAngle = self.HighlightAngle + 0.3
		render.DrawSprite(self:GetPos(),32 + math.sin(self.HighlightAngle) * 1.5,32 + math.sin(self.HighlightAngle) * 1.5,Color(255,255,255,255))
	end
end

//****************************************************
//* Renders a curve segment wrt the parameters
function ENT:DrawCurveSegment(material, thickness, pA, dA, pB, dB)

	if CLIENT and gDisplayJunk == true then

		if (not pB or not dB or not pA or not dA) then
			return
		end
		
		local curveRes = 7

		render.SetMaterial(material)
		render.StartBeam(curveRes + 1)

		local posA = pA
		local posB = pA + dA
		local posC = pB - dB
		local posD = pB

		render.AddBeam(posA, thickness, 0, Color(255,255,255))
		for i = 1, curveRes do

			local a = i / curveRes
			local b = 1.0 - a

			local posCurve = (posD * (a * a * a)) + (posC * (3 * a * a * b)) + (posB * (3 * a * b * b)) + (posA * (b * b * b))
			render.AddBeam(posCurve, thickness, a, Color(255,255,255))

		end
		render.AddBeam(posD, thickness, 1, Color(255,255,255))

		render.EndBeam()
	
	end
end

//****************************************************
//* Evaluates the curve segment and returns a position
//* on it. Only to be used by the root node
function ENT:EvaluateTrackSegment(firstNode, secondNode, frac)

	local position = Vector(0,0,0)

	if frac >= 0.0 and frac <= 1.0 and self.BaseClass.IsValid(self, firstNode) and self.BaseClass.IsValid(self, secondNode) then

			local a = frac
			local b = 1.0 - a

			local posA = firstNode:GetPos()
			local posB = (firstNode:GetPos() - firstNode:GetNWVector(ID_PATH_DIRECTION))
			local posC = (secondNode:GetPos() + secondNode:GetNWVector(ID_PATH_DIRECTION))
			local posD = secondNode:GetPos()

			position = (posD * (a * a * a)) + (posC * (3 * a * a * b)) + (posB * (3 * a * b * b)) + (posA * (b * b * b))

	end

	//print(position)
	return position
end

//****************************************************
//* Returns the length of the curve segment 
function ENT:GetTrackSegmentLength(firstNode, secondNode)

	local length = 0.0

	if self.BaseClass.IsValid(self, firstNode) and self.BaseClass.IsValid(self, secondNode) then

		local posA = firstNode:GetPos()
		local posB = self.BaseClass.EvaluateTrackSegment(self, firstNode, secondNode, 0.25)
		local posC = self.BaseClass.EvaluateTrackSegment(self, firstNode, secondNode, 0.5)
		local posD = self.BaseClass.EvaluateTrackSegment(self, firstNode, secondNode, 0.75)
		local posE = secondNode:GetPos()

		length = posA:Distance(posB) + posB:Distance(posC) + posC:Distance(posD) + posD:Distance(posE)
		
	end

	//print(position)
	return position
end

//****************************************************
//* Renders this nodes track segment wrt the track
function ENT:DrawTrackSegment(material, thickness, showTangents)

	if CLIENT then

		local nextNode = self.BaseClass.GetNextNode(self)

		if not self.BaseClass.IsValid(self,nextNode) then
			return
		end

		local curveRes = 7

		render.SetMaterial(material)
		render.StartBeam(curveRes + 1)

		local posA = self:GetPos()
		local posB = (self:GetPos() - self:GetNWVector(ID_PATH_DIRECTION))
		local posC = (nextNode:GetPos() + nextNode:GetNWVector(ID_PATH_DIRECTION))
		local posD = nextNode:GetPos()

		render.AddBeam(posA, thickness, 0, Color(255,255,255))
		for i = 1, curveRes do

			local a = i / curveRes
			local b = 1.0 - a

			local posCurve = (posD * (a * a * a)) + (posC * (3 * a * a * b)) + (posB * (3 * a * b * b)) + (posA * (b * b * b))

			render.AddBeam(posCurve, thickness, a, Color(255,255,255))

		end
		render.AddBeam(posD, thickness, 1.0, Color(255,255,255))

		render.EndBeam()

		if showTangents == true then
			//Render control lines
			render.SetMaterial(self.Materials ["CameraTan"])
			render.StartBeam(2)
			render.AddBeam(posA - self:GetNWVector(ID_PATH_DIRECTION), thickness, 1, Color(255,255,255))
			render.AddBeam(posA + self:GetNWVector(ID_PATH_DIRECTION), thickness, 1, Color(255,255,255))
			render.EndBeam()
		end
	
	end
end

//****************************************************
//* Renders a straight segment to the next node
function ENT:DrawStraightTrackSegment(material, thickness)

	if CLIENT then

		local nextNode = self.BaseClass.GetNextNode(self)
		if self.BaseClass.IsValid(self,nextNode) then
			render.SetMaterial(material)
			render.StartBeam(2)

			render.AddBeam(self:GetPos(), thickness, 0.0, Color(255,255,255))
			render.AddBeam(nextNode:GetPos(), thickness, 1.0, Color(255,255,255))

			render.EndBeam()
		end
	end
end

local NUMBER_WIDTH = 15
local NUMBER_OFFSET = Vector(0,0,20)
local NUMBER_HEIGHT = 15
function ENT:DrawNumber()

	if CLIENT then

		local val = self:GetNWInt(ID_NODE_ID)
		local firstDigit = nil
		local secondDigit = nil 
		local thirdDigit = nil

		if(val < 0) then
			val = -1 * val
			firstDigit = "13"	//negative symbol
		end

		if(val < 10) then

			if firstDigit then
				secondDigit = val
			else
				firstDigit = val
			end

		elseif(val == 10) then

			if(firstDigit)then
				secondDigit = "1"
				thirdDigit = "0"
			else
				firstDigit = "1"
				secondDigit = "0"
			end

		elseif(val > 10 && val < 100) then

			local modval = val % 10
			local unmodval = math.floor(val / 10) 

			if firstDigit then
				thirdDigit = ""..modval
				secondDigit = ""..unmodval
			else
				secondDigit = ""..modval
				firstDigit = ""..unmodval
			end

		end

		local labelDirection = Vector(1,0,0)
		local right = Vector(0,1,0)
		cam.Start3D2D(self:GetPos() + NUMBER_OFFSET, LocalPlayer():GetAngles(), 1)

			if firstDigit then
				render.SetMaterial( Material("sprites/num_" .. firstDigit))
				render.DrawQuadEasy( (right * NUMBER_WIDTH * 0), labelDirection, NUMBER_WIDTH, NUMBER_HEIGHT, Color(255,255,255,255),180)
			end

			if secondDigit then
				render.SetMaterial( Material("sprites/num_" .. secondDigit))
				render.DrawQuadEasy( (right * NUMBER_WIDTH * 1), labelDirection, NUMBER_WIDTH, NUMBER_HEIGHT, Color(255,255,255,255),180)
			end

			if thirdDigit then
				render.SetMaterial( Material("sprites/num_" .. thirdDigit))
				render.DrawQuadEasy( (right * NUMBER_WIDTH * 2), labelDirection, NUMBER_WIDTH, NUMBER_HEIGHT, Color(255,255,255,255),180)
			end

		cam.End3D2D()
	end
end

local NAME_OFFSET = Vector(0,0,30)
function ENT:DrawTrackNodeData()
	if CLIENT then
		
		local offsetPos = self:GetPos() + NAME_OFFSET
		local pos = offsetPos:ToScreen()
		
		local distance = LocalPlayer():GetPos():Distance(offsetPos)

		local alpha = 0

		if distance < 500 then
			alpha = 255
		elseif distance > 700 then
			alpha = 0
		else


			alpha = 255 * (1 - ((distance - 500) / (700 - 500)))

		end

		local black = Color( 176, 176, 176, alpha)
		local tipcol = Color( 46, 46, 46,  alpha)
		
		local nameVal = self.BaseClass.GetName(self)

		local x = 0
		local y = 0
		local padding = 15
		
		surface.SetFont( "Default" )
		local w, h = surface.GetTextSize( nameVal)
		
		x = pos.x - 1 * (0.5 * w )
		y = pos.y - 1 * (0.5 * h )
		
		cam.Start2D()
		draw.RoundedBox( 1, x-padding, y-padding, w+padding*2, h+padding*2, tipcol )
				
		draw.NoTexture()
		surface.SetDrawColor( tipcol.r, tipcol.g, tipcol.b, tipcol.a )

		draw.DrawText(nameVal, "Default", x - 0*w/2, y, black, TEXT_ALIGN_LEFT )
		cam.End2D()
	end
end
